package br.com.monitorimoveis.comum.persistencia.impl;

import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import javax.sql.DataSource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import br.com.monitorimoveis.comum.entidade.Anuncio;
import br.com.monitorimoveis.comum.persistencia.IAnuncioDAO;

@Service
public class AnuncioDAO implements IAnuncioDAO {

	@Autowired
	private SessionFactory sf;

	public void inserir(Anuncio anuncio) {
		getSession().save(anuncio);
	}

	public void atualizar(Anuncio anuncio) {
		getSession().merge(anuncio);
	}

	public Anuncio getById(int idAnuncio) {
		return (Anuncio) getSession().get(Anuncio.class, idAnuncio);
	}

	public Anuncio getByCodigo(int codigo) {
		Query query = getSession().createQuery(
				" from Anuncio where codigo = :codigo");

		query.setParameter("codigo", codigo);

		@SuppressWarnings("rawtypes")
		List result = query.list();
		if (result == null || result.size() == 0) {
			return null;
		}

		return (Anuncio) result.get(0);
	}

	@SuppressWarnings("unchecked")
	public List<Anuncio> listAll() {
		Criteria criteria = getSession().createCriteria(Anuncio.class);

		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public List<Anuncio> listByCidade(String cidade) {

		Criteria criteria = getSession().createCriteria(Anuncio.class);
		criteria.add(Restrictions.eq("cidade", cidade));

		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public List<Anuncio> listByBairroCidade(String cidade, String bairro) {

		Criteria criteria = getSession().createCriteria(Anuncio.class);
		criteria.add(Restrictions.eq("cidade", cidade));
		criteria.add(Restrictions.eq("bairro", bairro));

		return criteria.list();
	}

	public Session getSession() {
		return sf.getCurrentSession();
	}

	public void deletarAnunciosDuplicados() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"spring.xml");
		DataSource ds = (DataSource) context.getBean("dataSource");

		Connection con = null;
		Statement st = null;
		ResultSet rs = null;

		try {
			con = ds.getConnection();
			st = con.createStatement();

			String queryCodigosComDuplicacao = "SELECT duplicados.codigo FROM (SELECT codigo, count(codigo) as num FROM anuncio GROUP BY codigo ORDER BY num desc) AS duplicados WHERE duplicados.num > 1";

			rs = st.executeQuery(queryCodigosComDuplicacao);


			StringBuffer queryAnuncios = new StringBuffer(
					"SELECT idAnuncio, codigo FROM anuncio WHERE codigo in (-1");

			while (rs.next()) {
				queryAnuncios.append(", " + rs.getInt(1));
				System.out.println("Código: " + rs.getInt(1));
			}

			queryAnuncios.append(") order by codigo, idAnuncio");
			System.out.println("Query: " + queryAnuncios.toString());

			rs = st.executeQuery(queryAnuncios.toString());

			StringBuffer queryDelete = new StringBuffer(
					"DELETE FROM Anuncio WHERE idAnuncio in (-1");

			int codigo = 0, codigoAnterior = 0, count = 0;

			while (rs.next()) {
				codigo = rs.getInt("codigo");

				if (codigo == codigoAnterior) {
					queryDelete.append(", " + rs.getInt("idAnuncio"));
					count++;
				}

				codigoAnterior = codigo;
			}

			queryDelete.append(")");
			System.out.println(queryDelete.toString());
			
			st.execute(queryDelete.toString());

			System.out.println("Foram deletados " + count + " anuncios que estavam duplicados!");
 			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void deletarHistoricosDuplicados() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"spring.xml");
		DataSource ds = (DataSource) context.getBean("dataSource");

		Connection con = null;
		Statement st = null;
		ResultSet rs = null;

		try {
			con = ds.getConnection();
			st = con.createStatement();

			String queryHistComDuplicacao = "SELECT idAnuncio FROM (SELECT idAnuncio, data, COUNT(idAnuncio) AS num FROM precohistanuncio GROUP BY idAnuncio, data ORDER BY num DESC) AS duplicados WHERE duplicados.num > 1";

			rs = st.executeQuery(queryHistComDuplicacao);

			StringBuffer queryHistoricos = new StringBuffer(
					"SELECT idPrecoHistAnuncio, idAnuncio, data FROM precoHistAnuncio WHERE idAnuncio in (-1");

			while (rs.next()) {
				queryHistoricos.append(", " + rs.getInt(1));
				System.out.println("ID ANUNCIO: " + rs.getInt(1));
			}

			queryHistoricos.append(") order by idAnuncio, data");
			System.out.println("Query: " + queryHistoricos.toString());

			rs = st.executeQuery(queryHistoricos.toString());

			StringBuffer queryDelete = new StringBuffer(
					"DELETE FROM precoHistAnuncio WHERE idPrecoHistAnuncio in (-1");

			int anuncio = 0, anuncioAnterior = 0, count = 0;
			Date data = new Date(0L), dataAnterior = new Date(0L);

			while (rs.next()) {
				anuncio = rs.getInt("idAnuncio");
				data = rs.getDate("data");
				
				if (anuncio == anuncioAnterior && data.equals(dataAnterior)) {
					queryDelete.append(", " + rs.getInt("idPrecoHistAnuncio"));
					count++;
				}

				anuncioAnterior = anuncio;
				dataAnterior = data;
			}

			queryDelete.append(")");
			System.out.println(queryDelete.toString());
			
			st.execute(queryDelete.toString());

			System.out.println("Foram deletados " + count + " anuncios que estavam duplicados!");
 			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
}
